#pragma once

#ifdef _OPENGL
#include <GL\glew.h>
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
#endif

#ifdef _DIRECTX
#include <d3dx9.h>
#endif

// Optimization flags for special case scenarios
enum BufferUsageFlags {
	NO_RENDER = 1,	// buffer is not going to be used to render geometry
	READ_WRITE = 2,	// device buffer is going to be read by the application
	DYNAMIC = 4,	// buffer is going to be used for dynamic geometry (multiple write)
};

class Buffer {
protected:
	unsigned int m_UsageFlags;

	
#ifdef _OPENGL
	GLenum glBufferUsageFlag() {
		switch(m_UsageFlags) {
		case NO_RENDER:
		case NO_RENDER | READ_WRITE:
			return GL_STATIC_READ;
		case NO_RENDER | DYNAMIC:
		case NO_RENDER | DYNAMIC | READ_WRITE:
			return GL_DYNAMIC_READ;
		case DYNAMIC:
			return GL_DYNAMIC_DRAW;
		case DYNAMIC | READ_WRITE:
			return GL_DYNAMIC_COPY;
		case READ_WRITE:
			return GL_STATIC_COPY;
		default:
			return GL_STATIC_DRAW;
		}
	}
#endif

#ifdef _DIRECTX
#endif

public:

	Buffer(unsigned int usageFlags): m_UsageFlags(usageFlags) {}
	virtual ~Buffer() {}

	bool isDynamic() {
		return m_UsageFlags & DYNAMIC;
	}

	bool isWriteOnly() {
		return !(m_UsageFlags & READ_WRITE);
	}

	bool isReadWrite() {
		return (m_UsageFlags & READ_WRITE);
	}

	bool isRenderable() {
		return !(m_UsageFlags & NO_RENDER);
	}

	unsigned int getUsageFlags() {
		return m_UsageFlags;
	}


};